package carsharing;

import java.util.ArrayList;
import java.util.List;
import java.util.ListIterator;
import java.util.Vector;

import carsharing.Stop.StopType;

public class Driver {
	
	private int memberId;
	private boolean available;
	private Coordinates source;
	private Coordinates destination;
	private int carrying;
	private List<Stop> stops = new ArrayList<Stop>();
	private int dist;
	
	public Driver(int id, Coordinates source, Coordinates destination){
		available = true;
		memberId = id;
		carrying = 0;
		this.source = source;
		this.destination = destination;
	}

	public Driver copy() {
		Driver aux = new Driver(this.memberId, this.source.copy(), this.destination.copy());
		aux.available = this.available;
		aux.carrying = this.carrying;
		aux.dist = this.dist;
		aux.stops = new ArrayList<Stop>();
		for(int i = 0; i < this.stops.size(); ++i) {
			aux.stops.add(this.stops.get(i).copy());
		}
		return aux;
	}
	public boolean isAvailable() {
		return available;
	}

	public void setAvailable(boolean available) {
		this.available = available;
	}

	public int getCarrying() {
		return carrying;
	}
	
	public void setCarrying(int carrying) {
		this.carrying = carrying;
	}

	public int getMemberId() {
		return memberId;
	}

	public void setMemberId(int memberId) {
		this.memberId = memberId;
	}

	public Coordinates getSource() {
		return source;
	}

	public void setSource(Coordinates source) {
		this.source = source;
	}

	public Coordinates getDestination() {
		return destination;
	}

	public void setDestination(Coordinates destination) {
		this.destination = destination;
	}

	public int getDist() {
		return dist;
	}
	
	public void calculateDist() {
		dist = 0;
		ListIterator<Stop> iter;
		iter = stops.listIterator();
		Coordinates aux1 = iter.next().getCoord();
		Coordinates aux2 = null;
		while(iter.hasNext()) {
			aux2 = iter.next().getCoord();
			dist = dist + aux2.distance(aux1);
			aux1 = aux2;
		}
	}
	
	
	//Add a stop to the list, sorted by minimum distance to the previous stops added
	public void addStop(Stop s) {
		stops.add(stops.size() - 1, s);
	}
	public void addInitialStop(Stop s) {
		stops.add(s);
	}
	
	
	public void delStops(int memId) {
		if(memId == memberId) return;//if try to delete obligatory stops of the driver
		
		for (int i = 0; i < stops.size(); i++) {
			Stop s = stops.get(i);
			if (s.getMemberId() == memId) {
				--i;
				stops.remove(s);
			}
		}
	}
	
	
	public void printStops() {
		ListIterator<Stop> iter;
		iter = stops.listIterator();
		for(int i = 0; i < stops.size(); i++) {
			iter.next().print();
			System.out.print(" | ");
		}
	}
	
	public int nStops() {
		return stops.size();
	}

	public void swapStops(int i, int j) {
		if(i == j) return;
		Stop aux2 = stops.remove(j + 1);
		Stop aux = stops.remove(i + 1);
		stops.add(i + 1, aux2);
		stops.add(j + 1, aux);
	}
	public void swapStops1(int i, int j) {
		if(i == j) return;
		Stop aux2 = stops.remove(j);
		Stop aux = stops.remove(i);
		stops.add(i, aux2);
		stops.add(j, aux);
	}
	
	public boolean preCheckStops(int x) {
		if(x == 1) {
			if(stops.get(1).getStopType() == StopType.DROP) return false;
		}
		else if(x%2 == 1 && stops.get(x - 1).getStopType() == stops.get(x).getStopType()) return false;
		return true;
	}

	public boolean checkStops() {
		if(stops.get(1).getStopType() == StopType.DROP) return false;
		
		for(int i = 1; i < stops.size() - 1; i++) {
			int idMidPick = -1;
			int midPicks = 0;
			boolean found = false;
			if(stops.get(i).getStopType() == StopType.PICK) {
				++midPicks;
				for (int j = i+1; j < stops.size() - 1 && !found && midPicks <= 2; j++) {
					if(stops.get(j).getStopType() == StopType.DROP) {
						if(stops.get(i).getMemberId() == stops.get(j).getMemberId()) {
							//We have the corresponding DROP
							found = true;
						}
						else if(midPicks == 2 && idMidPick == stops.get(j).getMemberId()){
							--midPicks;
							idMidPick = -1;
						}
						//else return false;
					}
					else if(stops.get(j).getStopType() == StopType.PICK) {
						idMidPick = stops.get(j).getMemberId();
						++midPicks;
					}
				}
				if(midPicks > 2) return false;
			}
			else {//it's a drop
				for(int j = i - 1; j > 0 && !found; --j) {
					if(stops.get(j).getStopType() == StopType.PICK && 
						stops.get(i).getMemberId() == stops.get(j).getMemberId()) {
							found = true;
											}
				}
				if(!found) return false;
			}
		}
		return true;
	}


}
